<template>
  <div class="container">
    <!-- 上传文件 -->
    <n-upload :default-upload="false" :max="1" accept=".xlsx,.xls" @change="handleUploadFileChange">
      <n-button>上传文件</n-button>
    </n-upload>
    <!-- 分割线 -->
    <n-divider />
    <!-- 上传文件前 -->
    <div v-if="!uploadFile">
      <!-- 渐变文字提示 -->
      <n-gradient-text
        :gradient="{
          from: 'rgb(85, 85, 85)',
          to: 'rgb(170, 170, 170)',
        }"
      >
        请先上传文件...（加载过程中，依据文件大小可能存在卡顿）
      </n-gradient-text>
    </div>
    <!-- 上传文件后 -->
    <div v-if="uploadFile">
      <!-- 标题 -->
      <n-h4 prefix="bar">
        <n-text type="primary"> 勾选要转换的字段 </n-text>
      </n-h4>
      <!-- 勾选字段组 -->
      <n-checkbox-group v-model:value="selectedFields">
        <n-flex>
          <n-checkbox v-for="field in fields" :key="field" :value="field" :label="field" />
        </n-flex>
      </n-checkbox-group>
      <!-- 分割线 -->
      <n-divider />
      <!-- 转换按钮 -->
      <n-button class="ml-2!" type="primary" @click="handleExcelToJSON">转换</n-button>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { useConfigStore } from "@renderer/store/config";
import { UploadFileInfo } from "naive-ui";
import { read, utils } from "xlsx";

// 全局配置
const useConfig = useConfigStore();
// 消息提示
const message = useMessage();
// 上传的文件
const uploadFile = ref<File | null>(null);
// 上传的数据
const uploadData = ref<{ key: string; value: any }[]>([]);
// 文件名
const fileName = ref<string>("");
// 表格宽度
const containerWidth = computed(() => {
  return useConfig.collapsed ? "72px" : "224px";
});

// 上传文件事件
const handleUploadFileChange = async (options: { file: UploadFileInfo; fileList: Array<UploadFileInfo>; event?: Event }) => {
  // 文件变化检测
  if (options.fileList.length == 0) {
    uploadFile.value = null;
    uploadData.value = [];
    return;
  }

  // 格式验证
  if (!["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel"].includes(options.file.type as string)) {
    message.error("请上传Excel文件（.xlsx 或 .xls）");
    uploadFile.value = null;
    uploadData.value = [];
    return;
  }

  // 获取文件
  uploadFile.value = options.file.file!;
  // 文件名
  fileName.value = options.file.name.split(".")[0];

  // 读取文件
  const arrayBuffer = await uploadFile.value.arrayBuffer();

  // 读取文件
  const workbook = read(arrayBuffer);
  // 获取第一个工作表
  const worksheet = workbook.Sheets[workbook.SheetNames[0]];
  // 指定了选项 header: 1 将生成一个数组的数组
  const workData = utils.sheet_to_json(worksheet, { header: 1 });
  // 表头
  const headers = workData[0] as string[];
  // 字段列表
  fields.value.length = 0;
  headers.forEach((item) => {
    fields.value.push(item);
  });
  //   默认全部填充
  selectedFields.value = fields.value;

  // 缓存数据
  uploadData.value = utils.sheet_to_json(worksheet);
};

// 字段列表
const fields = ref<string[]>([]);
// 选择的字段
const selectedFields = ref<string[]>([]);

// 转换事件
const handleExcelToJSON = () => {
  const data: any[] = [];

  // 转换为数组的excel数据
  for (let i = 0; i < uploadData.value.length; i++) {
    const uploadDataItem = uploadData.value[i];

    // 被勾选的保留字段
    for (let j = 0; j < selectedFields.value.length; j++) {
      const selectedFieldItem = selectedFields.value[j];

      // 对比筛选
      if (uploadDataItem[selectedFieldItem]) {
        // 初始化
        if (!data[i]) {
          data[i] = {};
        }
        // 保留数据
        data[i][selectedFieldItem] = uploadDataItem[selectedFieldItem];
      }

      // 跳过
      continue;
    }
  }

  // 导出文件
  const blob = new Blob([JSON.stringify(data)], { type: "application/json;charset=utf-8" });
  const a = document.createElement("a");
  a.href = URL.createObjectURL(blob);
  a.download = fileName.value + ".json";
  a.click();
  URL.revokeObjectURL(a.href);
};
</script>

<style lang="scss" scoped>
#container {
  width: calc(100vw - v-bind(containerWidth));
}
</style>
